import 'ace-builds/src-noconflict/mode-sql';

// Apply custom folding rules
const Range = ace.require("ace/range").Range;
const SqlMode = ace.require("ace/mode/sql").Mode;
const BaseFoldMode = ace.require("ace/mode/folding/fold_mode").FoldMode;

// 自定义 SQL 折叠规则
const SqlFoldMode = function() {
    this.foldingStartMarker = /\bSELECT\b|\bCASE\b|\(/i;
    this.foldingStopMarker = /\bEND\b|\)/i;
};

SqlFoldMode.prototype = Object.create(BaseFoldMode.prototype);
SqlFoldMode.prototype.constructor = SqlFoldMode;

SqlFoldMode.prototype.getFoldWidget = function(session, foldStyle, row) {
    const line = session.getLine(row);
    if (this.foldingStartMarker.test(line)) {
        return "start";
    }
    if (this.foldingStopMarker.test(line)) {
        return "end";
    }
    return "";
};

SqlFoldMode.prototype.getFoldWidgetRange = function(session, foldStyle, row) {
    const line = session.getLine(row);
    const match = line.match(this.foldingStartMarker);
    if (match) {
        const startColumn = match.index + match[0].length;
        const startRow = row;

        const maxRow = session.getLength();
        let endRow = row;
        let endColumn = line.length;

        let openBrackets = 0;
        let openCases = 0;

        while (++row < maxRow) {
            const line = session.getLine(row);
            if (line.match(this.foldingStartMarker)) {
                if (line.indexOf('(') !== -1) {
                    openBrackets++;
                } else if (/CASE/i.test(line)) {
                    openCases++;
                }
            }
            const stopMatch = line.match(this.foldingStopMarker);
            if (stopMatch) {
                if (stopMatch[0] === ')') {
                    if (openBrackets === 0) {
                        endRow = row;
                        endColumn = stopMatch.index + stopMatch[0].length;
                        break;
                    } else {
                        openBrackets--;
                    }
                } else if (/END/i.test(stopMatch[0]) && openBrackets === 0) {
                    if (openCases === 0) {
                        endRow = row;
                        endColumn = stopMatch.index + stopMatch[0].length;
                        break;
                    } else {
                        openCases--;
                    }
                }
            }
        }

        if (endRow > startRow) {
            return new Range(startRow, startColumn, endRow, endColumn);
        }
    }
};

export default SqlFoldMode;
